<template>
  <Dialog v-model="dialogVisible" title="角色权限设置">
    <el-card class="w-full h-400px !overflow-y-scroll" shadow="never">
      <template #header>
        全部展开/折叠:
        <el-switch
          v-model="menuExpand"
          active-text="展开"
          inactive-text="折叠"
          inline-prompt
          @change="handleCheckedTreeExpand"
        />
      </template>
      <el-tree
        ref="treeRef"
        :data="resourceOptions"
        :props="defaultProps"
        :default-checked-keys="defaultCheckedKeys"
        empty-text="加载中，请稍候"
        node-key="id"
        show-checkbox
        check-strictly
        @check-change="handleCheckChange"
      />
    </el-card>
  </Dialog>
</template>
<script lang="ts" setup>
import { defaultProps, handleTree } from '@/utils/tree'
import * as RoleApi from '@/api/system/role'
import * as MenuApi from '@/api/system/menu'

defineOptions({ name: 'SystemRoleAssignMenuForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const defaultCheckedKeys = ref<string[]>([])
let dataId: number | undefined = undefined
const formRef = ref() // 表单 Ref
const resourceOptions = ref<any[]>([]) // 菜单树形结构
const menuExpand = ref(false) // 展开/折叠
const treeRef = ref() // 菜单树组件 Ref

/** 打开弹窗 */
const open = async (id: number) => {
  dialogVisible.value = true
  resetForm()
  // 加载 Menu 列表。注意，必须放在前面，不然下面 setChecked 没数据节点
  resourceOptions.value = handleTree(await MenuApi.getSimpleMenusList())
  // 设置数据
  dataId = id
  formLoading.value = true
  try {
    // 设置默认选中的key
    defaultCheckedKeys.value = await RoleApi.getAssignedResourceCodes(id)
  } finally {
    formLoading.value = false
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调

/** 重置表单 */
const resetForm = () => {
  // 重置选项
  menuExpand.value = false
  // 重置表单
  defaultCheckedKeys.value = []
  resourceOptions.value = []
  formRef.value?.resetFields()
}

/** 展开/折叠全部 */
const handleCheckedTreeExpand = () => {
  const nodes = treeRef.value?.store.nodesMap
  for (let node in nodes) {
    if (nodes[node].expanded === menuExpand.value) {
      continue
    }
    nodes[node].expanded = menuExpand.value
  }
}

// 节点选择发生变化时的回调
const handleCheckChange = (data: any, checked: boolean) => {
  console.log(data, checked)

  const reqBody: RoleApi.RoleAuthorizeVO = {
    roleId: dataId!,
    resourceId: data.id,
  }

  if (checked) {
    RoleApi.addAuthorized(reqBody).catch(() => {
      message.error(t('sys.api.operationFailed'))
    })
  } else {
    RoleApi.removeAuthorized(reqBody).catch(() => {
      message.error(t('sys.api.operationFailed'))
    })
  }
}
</script>
